package com.madzone.wiki.gae.ds;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.jdo.PersistenceManager;

import com.ecyrd.jspwiki.NoRequiredPropertyException;
import com.ecyrd.jspwiki.WikiEngine;
import com.ecyrd.jspwiki.auth.WikiSecurityException;
import com.ecyrd.jspwiki.auth.authorize.Group;
import com.ecyrd.jspwiki.auth.authorize.GroupDatabase;
import com.madzone.wiki.gae.ds.model.PMF;
import com.madzone.wiki.gae.ds.model.User;
import com.madzone.wiki.gae.ds.model.UserGroup;

public class GoogleDataStoreGroupDatabase implements GroupDatabase {
	
	private WikiEngine mWikiEngine;
	private Properties mProperties;

	@Override
	public void commit() throws WikiSecurityException {
		// Nothing to do
	}

	@Override
	public void delete(Group group) throws WikiSecurityException {
		UserGroup userGroup = UserGroup.getByGroupName(group.getName());
		userGroup.delete();
	}

	@Override
	public Group[] groups() throws WikiSecurityException {
		PersistenceManager pm = PMF.getPM();
		List<UserGroup> userGroups = UserGroup.getAllGroups();
		Group[] groups = new Group[userGroups.size()];
		int i = 0;
		for (UserGroup userGroup:userGroups) {
			groups[i] = new Group(userGroup.getName(), mWikiEngine.getApplicationName()){};
			groups[i].setCreated(userGroup.getCreated());
			groups[i].setCreator(userGroup.getCreator().getLoginName());
			groups[i].setLastModified(userGroup.getModified());
			groups[i].setModifier(userGroup.getModifier().getLoginName());
			i++;
		}
		//pm.close();
		return groups;
	}

	@Override
	public void initialize(WikiEngine engine, Properties props)
			throws NoRequiredPropertyException, WikiSecurityException {
		mWikiEngine = engine;
		mProperties = props;
	}

	@Override
	public void save(Group group, Principal modifier)
			throws WikiSecurityException {
		if( group == null || modifier == null )
        {
            throw new IllegalArgumentException( "Group or modifier cannot be null." );
        }
		String groupName = group.getName();
		UserGroup userGroup = UserGroup.getByGroupName(groupName);
		Date now = new Date();
		if (userGroup != null) {
			// Group is new: insert new group record
            userGroup.setModified(now);
            userGroup.setModifier(modifier.getName());


		} else {
			userGroup = new UserGroup();
			userGroup.setName(group.getName());
			userGroup.setCreated(group.getCreated());
			userGroup.setCreator(modifier.getName());
			userGroup.setModified(group.getLastModified());
			userGroup.setModifier(modifier.getName());
			group.setCreated( now );
            group.setCreator( modifier.getName() );
		}
		group.setLastModified( now );
        group.setModifier( modifier.getName() );
        
        //Clear existing members
        userGroup.setMembers(null);

        // Insert group member records
        List<User> membersList = new ArrayList<User>();
        Principal[] members = group.members();
        for( int i = 0; i < members.length; i++ )
        {
            Principal member = members[i];
            User user = User.getByFullName(member.getName());
            membersList.add(user);
        }
        userGroup.setMembers(membersList);
		userGroup.save();
	}

}
